/**
  ******************************************************************************
  * File Name          : weight.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "bsp.h"
#include "spiflash.h"
#include "tskcfg.h"
#include "route.h"
#include "network.h"

TaskHandle_t xRoute_Thd = NULL;
StaticTask_t xRoute_Tcb;
StackType_t  xRoute_Stk[ROUTE_STACK_SIZE];

/* 网络到本地数据包 */
QueueHandle_t Route_NetToLoc_Qhd = NULL;
static StaticQueue_t route_net_to_loc_stru;
static uint8_t       route_net_to_loc_area[ROUTE_NETTOLOC_QUE_LENGTH * ROUTE_NETTOLOC_QUE_ITEMSIZE];

/* everywhere到网络数据包 */
QueueHandle_t Route_EvewToNet_Qhd = NULL;
static StaticQueue_t route_evew_to_net_stru;
static uint8_t       route_evew_to_net_area[ROUTE_EVEWTONET_QUE_LENGTH  * ROUTE_EVEWTONET_QUE_ITEMSIZE];

/* 网络到485数据包 */
QueueHandle_t Route_EvewTo485_Qhd = NULL;
static StaticQueue_t route_evew_to_485_stru;
static uint8_t       route_evew_to_485_area[ROUTE_EVEWTO485_QUE_LENGTH * ROUTE_EVEWTO485_QUE_ITEMSIZE];

Route_ToPoListType     Route_NetTopoList, Route_LocalTopoList;
Route_TopoSyncListType Route_BoundList, Route_UnboundList;

Route_PayloadType Route_to_net_pub_back;
Route_PayloadType Route_net_to_loc_back;


static uint8_t route_gettop(void)
{
  uint8_t i;
	
	/* 刷新设备列表 */
	Route_RefreshDeviceList(NULL);
  
  if(Route_EvewToNet_Qhd == NULL)
  {
    return 1;
  }
  
  if(Route_NetToLoc_Qhd == NULL)
  {
    return 2;
  }
  
  for(i=0; i<3; i++)
  {
    Route_gw_tonet_gettopo();
		
    if(xQueueReceive(Route_NetToLoc_Qhd, &Route_net_to_loc_back, 15000) == pdTRUE)
    {
      if(Route_net_to_loc_back.trans_dir != ROUTE_TRSDIR_NET_TO_LOCAL)
      {
        continue;
      }
      
      if(Route_net_to_loc_back.dev_type != RT_DV_GW)
      {
        continue;
      }
      
      if(Route_net_to_loc_back.pl_type != ROUTE_PLTYP_GW_GETTP)
      {
        continue;
      }
      
      if(Route_net_to_loc_back.pl_len != sizeof(Route_pl_un_msg_Type))
      {
        continue;
      }
			
			if(((Route_pl_un_msg_Type *)Route_net_to_loc_back.payload)->msg == 0)
			{
				break;
			}
			else
			{
				SysDbgLog("Get TopoList err!\r\n");
				return 1;
			}
    }
  }
	
	if(i > 2)
	{
		return 2;
	}
	
	/* 获取需要绑定和解绑的设备 */
	Route_IsTopoMatchDevice();
	
  return 0;
}

static uint8_t route_addtop(uint8_t index)
{
  uint8_t i;
  
  if(Route_NetToLoc_Qhd == NULL)
  {
    return 2;
  }
	
	for(i=0; i<3; i++)
	{
		Route_gw_tonet_addtop(index);
		
		if(xQueueReceive(Route_NetToLoc_Qhd, &Route_net_to_loc_back, 15000) == pdTRUE)
		{
			if(Route_net_to_loc_back.trans_dir != ROUTE_TRSDIR_NET_TO_LOCAL)
      {
        continue;
      }
      
      if(Route_net_to_loc_back.dev_type != RT_DV_GW)
      {
        continue;
      }
      
      if(Route_net_to_loc_back.pl_type != ROUTE_PLTYP_GW_ADDTP)
      {
        continue;
      }
			
			if(Route_net_to_loc_back.pl_len != sizeof(Route_pl_un_msg_Type))
      {
        continue;
      }
			
			if(((Route_pl_un_msg_Type *)Route_net_to_loc_back.payload)->msg == 0)
			{
				return 0;
			}
			else
			{
				return 3;
			}
		}
	}

  return 4;
}

static uint8_t route_deltopo(uint8_t index)
{
	uint8_t i;
  
  if(Route_NetToLoc_Qhd == NULL)
  {
    return 2;
  }
    
	for(i=0; i<3; i++)
	{
		Route_gw_tonet_deltopo(index);
		
		if(xQueueReceive(Route_NetToLoc_Qhd, &Route_net_to_loc_back, 15000) == pdTRUE)
		{
			if(Route_net_to_loc_back.trans_dir != ROUTE_TRSDIR_NET_TO_LOCAL)
      {
        continue;
      }
      
      if(Route_net_to_loc_back.dev_type != RT_DV_GW)
      {
        continue;
      }
      
      if(Route_net_to_loc_back.pl_type != ROUTE_PLTYP_GW_DELTP)
      {
        continue;
      }
			
			if(Route_net_to_loc_back.pl_len != sizeof(Route_pl_un_msg_Type))
      {
        continue;
      }
			
			if(((Route_pl_un_msg_Type *)Route_net_to_loc_back.payload)->msg == 0)
			{
				return 0;
			}
			else
			{
				return 3;
			}
		}
	}

  return 4;
}

void vRoute_Task(void * pvParameters)
{
	uint8_t i;
	
	Route_NetToLoc_Qhd  = xQueueCreateStatic(ROUTE_NETTOLOC_QUE_LENGTH, ROUTE_NETTOLOC_QUE_ITEMSIZE,
	                                         route_net_to_loc_area, &route_net_to_loc_stru);

	Route_EvewToNet_Qhd = xQueueCreateStatic(ROUTE_EVEWTONET_QUE_LENGTH, ROUTE_EVEWTONET_QUE_ITEMSIZE,
	                                        route_evew_to_net_area, &route_evew_to_net_stru);
  
  Route_EvewTo485_Qhd = xQueueCreateStatic(ROUTE_EVEWTO485_QUE_LENGTH, ROUTE_EVEWTO485_QUE_ITEMSIZE,
	                                         route_evew_to_485_area, &route_evew_to_485_stru);
  
  while(1)
	{
    if(xQueueReceive(Route_NetToLoc_Qhd, &Route_net_to_loc_back, portMAX_DELAY) == pdTRUE)
		{
      if((Route_net_to_loc_back.trans_dir == ROUTE_TRSDIR_NET_TO_LOCAL) && \
				 (Route_net_to_loc_back.dev_type  == RT_DV_GW) && \
			   (Route_net_to_loc_back.pl_type   == ROUTE_PLTYP_GW_SBTB))
      {
        route_gettop();
				
				for(i=0; i< Route_UnboundList.num; i++)
				{
					route_deltopo(i);
				}
				
				for(i=0; i< Route_BoundList.num; i++)
				{
					route_addtop(i);
				}
				
				Route_gw_tonet_sblx();
      }
    }
	}
}

